TA
poke

[DxP] Exclusivo Poketibia OpenSource+Cliente+Site+DB

Por Taiger, 19 de jun. de 2016 em OTServer Alternativo (ATS)

poketibia
poke tibia
open source
opensource
dxp
poketibiadxp
dxp 2016
1.2k
268k
kttallanK
25 de julho de 2016 às 12:22
6 minutos atrás, Drakopoulos disse:

É que o client v1 aceita as sprites compiladas e os arquivos .lua em codificação Base64, já o v3 não.

Referente ao erro só por um if verificando se for null que n irá tar mais.

Bem pensando me passa ao o if.

 

No caso é do v3

xokysX
25 de julho de 2016 às 13:25

Alguém sabe se tem algo na source gerando lag?, npc, items

DrakopoulosD
25 de julho de 2016 às 13:44
19 minutos atrás, xokys disse:

Alguém sabe se tem algo na source gerando lag?, npc, items

Possa ser algum erro que esteja dando no server ou no client q está gerando essa lag. É sempre bom conferir na distro ou no console do otclient (ctrl + T).

xokysX
25 de julho de 2016 às 14:47

Na distro os erros que me recorrem são alguns dos que já foram reportados, o server está em uma vps muito boa para estar com este lag absurdo, vou ver se o client esta gerando algo!

Não estou usando o mapa que veio nele, estou usando o mapa do cyan!

DenuvoD
25 de julho de 2016 às 15:48

@xokys provável que seja o cliente, o @Drakopoulos me ajudou com o dele mas ainda assim continua dando lag... o fps cai muito e fica dando umas travadas, isso geralmente durante vários ataques simultâneos onde tem muito poke e tbm quando alguém entra na cam. Acho que se a gente conseguir resolver esse problema o serve fica jogável. 

xokysX
25 de julho de 2016 às 16:00

@Durant remova o comando !rank, e também os pcs de checar level, estão gerando muito consumo no mysql, você esta usando o client V3?

Hoje vou dar uma analisada nas requisições que o server faz para o db, o consumo é absurdo!

Na minha distro retorna muito este erro:

[Error - MoveEvent::executeStep] Call Stack overflow.

Para os que tem problemas em colocar a xp por estágio, podem alterar o arquivo PokeDeath.lua, e pegar o script do pokeexp.lua

O rate de loot está bem zoado, eu alterei os xml, e o rate do config.lua, mesmo assim ainda continua com o rate bem alto

kttallanK
25 de julho de 2016 às 17:50
Agora, xokys disse:

@Durant remova o comando !rank, e também os pcs de checar level, estão gerando muito consumo no mysql, você esta usando o client V3?

Hoje vou dar uma analisada nas requisições que o server faz para o db, o consumo é absurdo!

Na minha distro retorna muito este erro:

[Error - MoveEvent::executeStep] Call Stack overflow.

Para os que tem problemas em colocar a xp por estágio, podem alterar o arquivo PokeDeath.lua, e pegar o script do pokeexp.lua

O rate de loot está bem zoado, eu alterei os xml, e o rate do config.lua, mesmo assim ainda continua com o rate bem alto

Esse erro é referente a alguma criatura andando sobre um tipo de tile a qual não é possivel andar.

 

O rate do loot é baseado em % ou seja 10 é 10%, 0.6 é 0,6%.

xokysX
25 de julho de 2016 às 18:37

@kttallan depois vou dar uma olhada a fundo, mas o loot esta sendo influenciado por mais algo, stones estão com 1% de drop e mesmo assim caem toda hora

25 de julho de 2016 às 18:42

Remova todos os block das bordas das aguas, quando vc joga o poke nelas ele nao se mexe, fica travado nelas

Remover pelo OBJ e ItemEditor

@Alphapetboy

Transparencia das sprites é no lib/107-main tables.lua

JairKevickJ
25 de julho de 2016 às 19:10

Certos Players tem um problema com o cliente ! e outros n ! oque pode ser? 

6p4gtiV.png

DenuvoD
25 de julho de 2016 às 19:43

@xokys em relação ao loot acredito que tenha algo a mais que está influenciado mesmo, fiz a mesma coisa que vc e mesmo assim dropa stone toda hora :s

me explica ai melhor como faz pra alterar o XP pf, não entendi mt bem... tem algo haver com essas linhas?

 

Spoiler

if getPlayerLevel(pk) <= 50 then
             playerAddExp(party, expTotal * 200)  
elseif getPlayerLevel(pk) >= 51 and getPlayerLevel(pk) <= 75 then
             playerAddExp(party, expTotal * 130)
elseif getPlayerLevel(pk) >= 76 and getPlayerLevel(pk) <= 100 then
             playerAddExp(party, expTotal * 80)
elseif getPlayerLevel(pk) >= 101 and getPlayerLevel(pk) <= 150 then
             playerAddExp(party, expTotal * 40)
elseif getPlayerLevel(pk) >= 151 and getPlayerLevel(pk) <= 250 then
             playerAddExp(party, expTotal * 20)
elseif getPlayerLevel(pk) >= 251 and getPlayerLevel(pk) <= 350 then
             playerAddExp(party, expTotal * 10)
elseif getPlayerLevel(pk) >= 351 then
             playerAddExp(party, expTotal * 5)
             end
          end
      end
   elseif not isInParty(pk) then
if getPlayerLevel(pk) <= 50 then
playerAddExp(pk, math.floor(200 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 51 and getPlayerLevel(pk) <= 75 then
playerAddExp(pk, math.floor(130 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 76 and getPlayerLevel(pk) <= 100 then
playerAddExp(pk, math.floor(80 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 101 and getPlayerLevel(pk) <= 150 then
playerAddExp(pk, math.floor(40 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 151 and getPlayerLevel(pk) <= 250 then
playerAddExp(pk, math.floor(20 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 251 and getPlayerLevel(pk) <= 350 then
playerAddExp(pk, math.floor(10 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 351 then
playerAddExp(pk, math.floor(5 * givenexp * getDamageMapPercent(pk, cid)))
return true end      
   end  

 

Editado Julho 25 por Durant

jvcizidroJ
25 de julho de 2016 às 20:30
Em ‎24‎/‎06‎/‎2016 at 16:41, Durant disse:

@boxxer321 esse pesca.lua é o data\actions\scripts\Basic ou é o data\actions\scripts\fishing_system ? usa esse meu, lembrando que tem que alterar a posição, a posição 1 é o sqm que a machine tá e a 2 é o sqm que vc quer que o player esteja no pra poder usar, no caso enfrente a machine seria o recomendável.

 

opcode.lua

  Ocultar conteúdo

local op_crea = {

      OPCODE_SKILL_BAR = opcodes.OPCODE_SKILL_BAR,

      OPCODE_POKEMON_HEALTH = opcodes.OPCODE_POKEMON_HEALTH,

      OPCODE_BATTLE_POKEMON = opcodes.OPCODE_BATTLE_POKEMON,

      OPCODE_FIGHT_MODE = opcodes.OPCODE_FIGHT_MODE,

      OPCODE_WILD_POKEMON_STATS = opcodes.OPCODE_WILD_POKEMON_STATS,

      OPCODE_REQUEST_DUEL = opcodes.OPCODE_REQUEST_DUEL,

      OPCODE_ACCEPT_DUEL = opcodes.OPCODE_ACCEPT_DUEL,

      OPCODE_YOU_ARE_DEAD = opcodes.OPCODE_YOU_ARE_DEAD,

      OPCODE_DITTO_MEMORY = opcodes.OPCODE_DITTO_MEMORY,

}

function onExtendedOpcode(cid, opcode, buffer)

    if opcode == op_crea.OPCODE_SKILL_BAR then

        if buffer == "refresh" then

            doOTCSendPlayerSkills(cid)

        end

    elseif opcode == op_crea.OPCODE_POKEMON_HEALTH then

        if buffer == "refresh" then

            doOTCSendPokemonHealth(cid)

        end

    elseif opcode == op_crea.OPCODE_BATTLE_POKEMON then

        if buffer == "refresh" then

            if #getCreatureSummons(cid) >= 1 then

                doSendPlayerExtendedOpcode(cid, op_crea.OPCODE_BATTLE_POKEMON, tostring(getCreatureSummons(cid)[1]))

            end

        end

    elseif opcode == op_crea.OPCODE_FIGHT_MODE then

        setPlayerStorageValue(cid, storages.fightMode, tonumber(buffer))

    elseif opcode == op_crea.OPCODE_WILD_POKEMON_STATS then

        doSendPlayerExtendedOpcode(cid, op_crea.OPCODE_WILD_POKEMON_STATS, pokeStatus.getVity(tonumber(buffer)).."|"..pokeStatus.getAtk(tonumber(buffer)).."|"..pokeStatus.getSpAtk(tonumber(buffer)).."|"..pokeStatus.getDef(tonumber(buffer)).."|"..pokeStatus.getSpDef(tonumber(buffer)).."|"..pokeStatus.getSpeed(tonumber(buffer)))

    

    --//Duel

    elseif opcode == opcodes.OPCODE_REQUEST_DUEL then

           --legenda: cid = player, sid = player convidado

           local cut = string.explode(buffer, "/")

           local pokeballsCount, sid = tonumber(cut[1]), getCreatureByName(cut[2])

                if isCreature(sid) then 

                   doIniteDuel(cid, sid, pokeballsCount)

                end

    elseif opcode == opcodes.OPCODE_ACCEPT_DUEL then

        local p2 = getCreatureByName(buffer)

           if isInvitedDuel(p2, cid) then

               doPantinNoDuel(cid, p2, getPlayerStorageValue(p2, duelTable.infoBalls), 5)

           end

           

    elseif opcode == opcodes.OPCODE_DITTO_MEMORY then

         local item = getPlayerSlotItem(cid, 8):

            if item.uid == 0 then doSendMsg(cid, "Coloque seu shiny ditto no slot correto.") return true end

         local pokeName = getItemAttribute(item.uid, "poke")

            if pokeName ~= "Shiny Ditto" then return true end

            

            if isInArray({"saveMemory1", "saveMemory2", "saveMemory3"}, buffer) then

               local copyName = getItemAttribute(item.uid, "copyName")

               if pokeName == copyName then doSendMsg(cid, "Transforme seu ditto primeiro.") return true end

               if not fotos[doCorrectString(copyName)] then return true end

               if isPokeInSlots(getItemAttribute(item.uid, "memoryDitto"), doCorrectString(copyName)) then doSendMsg(cid, "Esta copia já está salva em um slot.") return true end

                   if buffer == "saveMemory1" then

                       doItemSetAttribute(item.uid, "memoryDitto", saveSlot(getItemAttribute(item.uid, "memoryDitto"), 1, getItemInfo(fotos[doCorrectString(copyName)]).clientId)) -- getPortraitClientID(doCorrectString(copyName))))

                   elseif buffer == "saveMemory2" then

                       doItemSetAttribute(item.uid, "memoryDitto", saveSlot(getItemAttribute(item.uid, "memoryDitto"), 2, getItemInfo(fotos[doCorrectString(copyName)]).clientId))

                   elseif buffer == "saveMemory3" then

                       doItemSetAttribute(item.uid, "memoryDitto", saveSlot(getItemAttribute(item.uid, "memoryDitto"), 3, getItemInfo(fotos[doCorrectString(copyName)]).clientId))

                   end

            elseif isInArray({"clearSlot1", "clearSlot2", "clearSlot3"}, buffer) then

                  if buffer == "clearSlot1" then

                       doItemSetAttribute(item.uid, "memoryDitto", saveSlot(getItemAttribute(item.uid, "memoryDitto"), 1, "?"))

                   elseif buffer == "clearSlot2" then

                       doItemSetAttribute(item.uid, "memoryDitto", saveSlot(getItemAttribute(item.uid, "memoryDitto"), 2, "?"))

                   elseif buffer == "clearSlot3" then

                       doItemSetAttribute(item.uid, "memoryDitto", saveSlot(getItemAttribute(item.uid, "memoryDitto"), 3, "?"))

                   end

            elseif isInArray({"use1", "use2", "use3"}, buffer) then

                  local summons = getCreatureSummons(cid)

                  if #summons < 1 then doSendMsg(cid, "Coloque seu ditto para fora da pokeball.") return true end

                  local pokeToTransform = getSlot(getItemAttribute(item.uid, "memoryDitto"), tonumber(buffer:explode("use")[1]))

                  doCopyPokemon(summons[1], pokeToTransform, true)

            end

               

               

            local memory = getItemAttribute(item.uid, "memoryDitto")

                  if not memory or memory == nil then

                     doItemSetAttribute(item.uid, "memoryDitto", "?|?|?")

                     memory = getItemAttribute(item.uid, "memoryDitto")

                  end

            local memoryOne, memoryTwo, memoryTree = memory:explode("|")[1], memory:explode("|")[2], memory:explode("|")[3]

            

            local str = memoryOne .. "-".. memoryTwo .."-" .. memoryTree

                  doSendPlayerExtendedOpcode(cid, opcodes.OPCODE_DITTO_MEMORY, str)

                  

                  

    elseif opcode == opcodes.OPCODE_TV_CAM then -- TVCam

            --doCreatePrivateChannel(cid)

            --doInviteToPrivateChannel(cid, playerName)

            --doRemoveIntoPrivateChannel(cid, playerName)

            if getGlobalStorageValue(globalsTV) == -1 then -- iniciar sistema

                setGlobalStorageValue(globalsTV, "")

            end

            local action = buffer:explode("/")[1]

            

            if action == "create" then

                createChannel(cid, buffer)

                

            elseif action == "close" then

                closeInClientChannmel(cid)

                

            elseif action == "watch" then

            

                local playerToWatch = getCreatureByName(buffer:explode("/")[2])

                   if isCreature(playerToWatch) then

                      if getPlayerStorageValue(playerToWatch, storages.playerTVPass) ~= "" and getPlayerStorageValue(playerToWatch, storages.playerTVPass) ~= "notASSenha" then

                         doSendPlayerExtendedOpcode(cid, opcodes.OPCODE_TV_CAM, "requestPass|" .. getPlayerStorageValue(playerToWatch, storages.playerTVPass) .. "|" .. buffer:explode("/")[2]) 

                      else

                         doWatch(cid, playerToWatch)

                      end

                    else

                     doSendMsg(cid, "Este player não está mais gravando.")

                   end

                   

            elseif action == "watchWithPass" then

            

                local playerToWatch = getCreatureByName(buffer:explode("/")[2])

                   if isCreature(playerToWatch) then

                      doWatch(cid, playerToWatch)

                   else

                     doSendMsg(cid, "Este player não está mais gravando.")

                   end

                   

            elseif action == "errou" then

                     doSendMsg(cid, "Senha do digitada incorreta.")

            end

            

    elseif opcode == opcodes.OPCODE_PLAYER_SHOW_AUTOLOOT then -- Autoloot

            if buffer:find("load/") then

              local itens = getAllItensAutoLoot()    

              doSendPlayerExtendedOpcode(cid, opcodes.OPCODE_PLAYER_SHOW_AUTOLOOT, (isCollectAll(cid) and "yes" or "no") .. "|" .. itens .. "|" .. getAllItensInMyListToClient(cid))

            elseif buffer:find("all") then

                doCollectAll(cid, true)

                doSendMsg(cid, "AutoLoot: Coletar tudo foi ativado.")

            elseif buffer:find("no") then

                doCollectAll(cid, false)

                doSendMsg(cid, "AutoLoot: Coletar tudo foi desativado.")

            else

              doSaveItems(cid, buffer)

            end

            

    elseif opcode == opcodes.OPCODE_PLAYER_SHOW_ONLINE then -- Janela de onlines do ADM

            doGetPlayersOnToADM(cid)

    elseif opcode == opcodes.OPCODE_PLAYER_SHOW_TRADE_HELD then

        local op = tonumber(buffer:explode("-")[2])

        local posP = getThingPos(cid)

        local posMachine = {{x = 959, y = 1122, z = 13}, {x = 958, y = 1122, z = 13}}

        if not doComparePositions(posMachine[1], posP) and not doComparePositions(posMachine[2], posP) then

           doSendMsg(cid, "Fique de frente com a maquina.")

           return true

        end

        if op == 1 then

           if doPlayerRemoveItem(cid, 15645, 20) then

              local tier = math.random(1, 2)

              doPlayerAddRandomHeld(cid, tier)

               else

              doSendMsg(cid, "Você precisa de 20 Devoted Tokens.")

           end

           return true 

        elseif op == 2 then

           if doPlayerRemoveItem(cid, 15644, 70) then

              local tier = math.random(1, 3)

              doPlayerAddRandomHeld(cid, tier)

               else

              doSendMsg(cid, "Você precisa de 70 Mighty Tokens.")

           end

           return true

        elseif op == 3 then

           if doPlayerRemoveItem(cid, 15644, 150) then

              local tier = math.random(2, 4)

              doPlayerAddRandomHeld(cid, tier)

               else

              doSendMsg(cid, "Você precisa de 150 Mighty Tokens.")

           end

           return true

        elseif op == 4 then

           if doPlayerRemoveItem(cid, 15644, 300) then

              local tier = math.random(2, 6)

              doPlayerAddRandomHeld(cid, tier)

               else

              doSendMsg(cid, "Você precisa de 300 Mighty Tokens.")

           end

           return true 

        elseif op == 5 then

           if doPlayerRemoveItem(cid, 15646, 30) then

              local tier = math.random(1, 3)

              doPlayerAddRandomHeld(cid, tier)

               else

              doSendMsg(cid, "Você precisa de 30 Hornored Tokens.")

           end

           return true 

        elseif op == 6 then

           if doPlayerRemoveItem(cid, 15646, 75) then

              local tier = math.random(2, 4)

              doPlayerAddRandomHeld(cid, tier)

               else

              doSendMsg(cid, "Você precisa de 75 Hornored Tokens.")

           end

           return true

        elseif op == 7 then

           if doPlayerRemoveItem(cid, 15646, 150) then

              local tier = math.random(3, 6)

              doPlayerAddRandomHeld(cid, tier)

               else

              doSendMsg(cid, "Você precisa de 150 Hornored Tokens.")

           end

           return true 

        end

    end

end

function getSlot(strings, slot)

    local slot1, slot2, slot3 = strings:explode("|")[1], strings:explode("|")[2], strings:explode("|")[3]

    local ret, flag = "", false

    for a, b in pairs(fotos) do

       if getItemInfo(fotos[a]).clientId == tonumber(slot1) and slot == 1 then 

          ret = doCorrectString(a)

          flag = true

       elseif getItemInfo(fotos[a]).clientId == tonumber(slot2) and slot == 2  then 

          ret = doCorrectString(a)

          flag = true

       elseif getItemInfo(fotos[a]).clientId == tonumber(slot3) and slot == 3 then 

          ret = doCorrectString(a)

          flag = true

       end

           if flag then

              break

           end    

    end

    return ret

end

function saveSlot(strings, slot, poke)

    local slot1, slot2, slot3 = strings:explode("|")[1], strings:explode("|")[2], strings:explode("|")[3]

    local finalSlots = (slot == 1 and poke .. "|" or slot1 .. "|") .. (slot == 2 and poke .. "|" or slot2 .. "|") .. (slot == 3 and poke .. "|" or slot3)

        return finalSlots

end

function isPokeInSlots(strings, poke)

    if not fotos[poke] then return false end

    poke = getItemInfo(fotos[poke]).clientId

    local slot1, slot2, slot3 = strings:explode("|")[1], strings:explode("|")[2], strings:explode("|")[3]

    if tonumber(slot1) == poke then

       return true

    elseif tonumber(slot2) == poke then

       return true

    elseif tonumber(slot3) == poke then

       return true

    end

    return false

end

 

 

 

OI O MEU NAO VAI, SO FICA APARECENDO QUE EU TENHO QUE FICAR EM FRENTE A MAQUINA

AlphapetboyA
25 de julho de 2016 às 21:07
10 horas atrás, kttallan disse:

@Drakopoulos

Esse do mega o segundo hit é referente a quantidade de offense que tem nas configurações dele..

 

Todos os bugs citados @Alphapetboy grande maioria é configuraveis, sobre o nome dos pokemons estarem superior a sprite é porquê o cliente da v3 está. Como posso dizer mais desatualizado vou deixar aqui o meu exe do OTcliente.

 

Executavel

Eu queria tirar uma dúvida com você sobre o remeres, tem como me ajudar? porque eu usei todos os remeres que me passaram para editar o mapa do servidor, porque vou criar um novo continente misturando todos os pokémon das gerações. BUT, SEMPRE quando vou carregar qualquer mapa, falha para carregar os spawns e houses. E isso não é em um RME especifico, são todos. O que pode ser isso? :/

JosegvbJ
25 de julho de 2016 às 22:23
4 horas atrás, kttallan disse:

Esse erro é referente a alguma criatura andando sobre um tipo de tile a qual não é possivel andar.

 

O rate do loot é baseado em % ou seja 10 é 10%, 0.6 é 0,6%.

 

na v1 n sei como demonios mexer na exp, ja tentei mexer na config.lua do servidor, tb na lib configuration em tds os locals pra mexer a exp e nemhum alterou em nd

xokysX
25 de julho de 2016 às 23:21

@Durant resolvi o problema do lag, retirei as sprites e itens e estou usando a do Cyan, o server esta rodando lindamente!

@Durant você vai pegar como base o script do pokeexp.lua

 if isInArray(list, party[i]) then		     
if getPlayerLevel(pk) <= 50 then
             playerAddExp(party[i], expTotal * 200)  
elseif getPlayerLevel(pk) >= 51 and getPlayerLevel(pk) <= 75 then
             playerAddExp(party[i], expTotal * 130)
elseif getPlayerLevel(pk) >= 76 and getPlayerLevel(pk) <= 100 then
             playerAddExp(party[i], expTotal * 80)
elseif getPlayerLevel(pk) >= 101 and getPlayerLevel(pk) <= 150 then
             playerAddExp(party[i], expTotal * 40)
elseif getPlayerLevel(pk) >= 151 and getPlayerLevel(pk) <= 250 then
             playerAddExp(party[i], expTotal * 20)
elseif getPlayerLevel(pk) >= 251 and getPlayerLevel(pk) <= 350 then
             playerAddExp(party[i], expTotal * 10)
elseif getPlayerLevel(pk) >= 351 then
             playerAddExp(party[i], expTotal * 5)
			 end
          end
      end
   elseif not isInParty(pk) then
if getPlayerLevel(pk) <= 50 then
playerAddExp(pk, math.floor(200 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 51 and getPlayerLevel(pk) <= 75 then
playerAddExp(pk, math.floor(130 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 76 and getPlayerLevel(pk) <= 100 then
playerAddExp(pk, math.floor(80 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 101 and getPlayerLevel(pk) <= 150 then
playerAddExp(pk, math.floor(40 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 151 and getPlayerLevel(pk) <= 250 then
playerAddExp(pk, math.floor(20 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 251 and getPlayerLevel(pk) <= 350 then
playerAddExp(pk, math.floor(10 * givenexp * getDamageMapPercent(pk, cid)))
elseif getPlayerLevel(pk) >= 351 then
playerAddExp(pk, math.floor(5 * givenexp * getDamageMapPercent(pk, cid)))
return true end	  

E vai até o script pokeDeath.lua e vera esta funçâo

 

function playerAddExp(cid, exp)
if not isCreature(cid) then return true end
	if isInPartyAndSharedExperience(cid) then
		local partyPlayers = getPartyMembers(getPlayerParty(cid))
		local partyExp = math.ceil(exp / #partyPlayers)
			  for i = 1, #partyPlayers do
				 if isPlayer(partyPlayers[i]) then
				    doPlayerAddExp(partyPlayers[i], partyExp * 30)
				    doSendAnimatedText(getThingPos(partyPlayers[i]), partyExp * 30, 215)
				 end
			  end
		return true
	end
	doPlayerAddExp(cid, exp * 30)
	doSendAnimatedText(getThingPos(cid), exp * 30, 215)
end

function doSendMsgInParty(cid, loot)
	if isInPartyAndSharedExperience(cid) then
		local partyPlayers = getPartyMembers(getPlayerParty(cid))
			  for i = 1, #partyPlayers do
				 if isPlayer(partyPlayers[i]) then
					doSendMsgToPartyChannel(partyPlayers[i], loot)
				 end
			  end
		return true
	end
end

 

É só integrar a pokeexp ai